﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DLM.Domain.Model;
using DLM.Infrastructure.Exception;
using DLM.Services.Interfaces;
using DLM.Web.ViewModel;
using Microsoft.Web.Helpers;
using Webdiyer.WebControls.Mvc;
using DLM.Services.Implementations;
using DLM.Infrastructure.Imaging;
using DLM.Web.MVC.Extensions;
using DLM.Infrastructure.Logging;

namespace DLM.Web.MVC.Controllers
{
    public class PartyController : Controller
    {

        private IPartyService partyService;
        private IUserService userService;
        private static string[] imageType = { "image/jpeg", "image/jpg", "image/pjpeg" };

        public PartyController(IPartyService partyService, IUserService userService)
        {
            this.partyService = partyService;
            this.userService = userService;
        }

        [HttpGet]
        public ActionResult List(int? page)
        {
            PagedList<Party> list = this.partyService.GetParty(page ?? 0, 20) as PagedList<Party>;
            return View(list);
        }

        [HttpGet]
        public ActionResult View(int? id, int? participantid, int? remarkid)
        {
            int pageIndex;
            int.TryParse(Request.QueryString["remarkid"], out pageIndex);

            if (participantid != null && Request.IsAjaxRequest())
            {
                var userList = this.userService.Participated(id ?? 0, participantid ?? 0, 12);
                return View("_Participant", userList);
            }
            if (remarkid != null && Request.IsAjaxRequest())
            {
                var remarkList = this.partyService.GetRemarkDTO(id ?? 0, pageIndex, 10);
                return View("_Remark", remarkList);
            }

            PartyDetailPageView view = new PartyDetailPageView();
            view = this.partyService.ViewParty(id ?? 0, User.Identity.Name);

            // view.party = this.partyService.GetParty(id ?? 0);
            // view.IsAttend = this.partyService.IsAttended(User.Identity.Name);
            // view.IsLead = this.partyService.IsLead(User.Identity.Name);

            view.Users = this.userService.Participated(id ?? 0, participantid ?? 0, 12);
            view.Remarks = this.partyService.GetRemarkDTO(id ?? 0, pageIndex, 10);
            view.Album = this.partyService.GetPartyAlbum(id ?? 0, 0, 8);
            return View(view);
        }

        [UserAuthorize]
        [HttpGet]
        public ActionResult Publish()
        {
            PartyPublishPageView pageView = new PartyPublishPageView();
            pageView.Type = this.partyService.GetPartyType()
                .Select(c => new SelectListItem { Text = c.Name, Value = c.PartyType.ToString() })
                .ToList<SelectListItem>();
            pageView.User = this.userService.GetUser(User.Identity.Name);
            return View(pageView);
        }

        [HttpGet]
        [UserAuthorize]
        public ActionResult FindModality(int? typeID)
        {
            if (!Request.IsAjaxRequest())
            {
                return null;
            }
            var list = this.partyService.GetModalityByType(typeID ?? 0)
                .Select(c => new SelectListItem { Text = c.Name, Value = c.MID.ToString() });

            return Json(list, JsonRequestBehavior.AllowGet);
        }

        [HttpGet]
        [UserAuthorize]
        public ActionResult FindSupplier(int? mid)
        {
            if (!Request.IsAjaxRequest())
            {
                return null;
            }
            var list = this.partyService.GetSupplier(mid ?? 0).OrderByDescending(c => c.Order)
                .Select(c => new SelectListItem { Text = c.Name, Value = c.Address.ToString() });
            return Json(list, JsonRequestBehavior.AllowGet);
        }


        [HttpPost]
        [UserAuthorize]
        public ActionResult Publish(Party party, CountrySelectionPageView countryView,FormCollection collection, HttpPostedFileBase uploadFile)
        {
            try
            {
                PartyPageView view = new PartyPageView();
                party.CreateDate = DateTime.Now;
                if (!string.IsNullOrEmpty(collection["txtModality"]))
                {
                    party.Modality = Server.HtmlEncode(collection["txtModality"].ToString());
                }

                if (string.IsNullOrEmpty(party.Modality) && string.IsNullOrEmpty(collection["txtModality"]))
                {
                    ModelState.AddModelError("Party.Modality", "请选择活动形式");
                    throw new ArgumentNullException("请选择活动形式");
                }

                if (countryView.SelectedProvince == null || countryView.SelectedProvince == "0"
                    || countryView.SelectedCity == "0" || countryView.SelectedCity == null
                    || countryView.SelectedZone == null || countryView.SelectedZone == "0")
                {
                    ModelState.AddModelError("Party.Location", "请选择活动地点");
                    throw new ArgumentNullException("请选择活动地点的省份，城市信息");
                }

                if (collection["txtLocation"] != null)
                {
                    party.Location = countryView.SelectedProvince + " " + countryView.SelectedCity + " " + countryView.SelectedZone + " " + Server.HtmlEncode(collection["txtLocation"].ToString());
                }
                else
                {
                    party.Location = countryView.SelectedProvince + " " + countryView.SelectedCity + " " + countryView.SelectedZone + " " + party.Location;
                }

                if (party.PartyType == (int)PartyType.HomeTown && string.IsNullOrEmpty(collection["ddlLxProvince"]))
                {
                    ModelState.AddModelError("Party.Modality", "请选择老乡范围");
                    throw new ArgumentNullException("请选择老乡范围信息");
                }
                if (collection["ddlLxProvince"] != null)
                {

                    party.Area = Server.HtmlEncode(collection["ddlLxProvince"].ToString()) + " " + Server.HtmlEncode(collection["ddlLxCity"].ToString());


                }
                if (party.PartyDate.Value >= party.EndDate)
                {
                    throw new ArgumentException("活动结束时间不能小于开始时间");
                }
                view.Party = party;
                view.UserName = User.Identity.Name;
                view.IsAuthenticated = User.Identity.IsAuthenticated;
                if (uploadFile != null)
                {
                    string title = Path.GetRandomFileName() + ".jpg";

                    //DateTime.Now.ToString() + DateTime.Now.Millisecond.ToString() + ".jpg";
                    party.PhotoUrl = "" + title;
                    string directory = Server.MapPath("~/Files/Party/" + party.PartyID.ToString() + "/");
                    string path = directory + title;

                    if (!Directory.Exists(directory))
                    {
                        Directory.CreateDirectory(directory);
                    }
                    // uploadFile.SaveAs(path);
                    Image.MakeThumbnailImg(uploadFile, this.Server.MapPath(path), 70, 90);
                }

                this.partyService.AddParty(view);
                return RedirectToAction("Default", "Home");
            }
            catch (PublishFailedException)
            {
                ModelState.AddModelError("", "您最近的活动时间距这次活动开始或结束时间间隔未超过一小时，不允许继续发布！");

                PartyPublishPageView pageView = new PartyPublishPageView();
                pageView.Type = this.partyService.GetPartyType()
                    .Select(c => new SelectListItem { Text = c.Name, Value = c.PartyType.ToString() })
                    .ToList<SelectListItem>();
                pageView.User = this.userService.GetUser(User.Identity.Name);
                party.Location = string.Empty;
                pageView.Party = party;

                return View(pageView);

            }
            catch (BounsNotEnoughException)
            {
                ModelState.AddModelError("", "您的积分不够，请充值后在发布活动！");
                PartyPublishPageView pageView = new PartyPublishPageView();
                pageView.Type = this.partyService.GetPartyType()
                    .Select(c => new SelectListItem { Text = c.Name, Value = c.PartyType.ToString() })
                    .ToList<SelectListItem>();
                pageView.User = this.userService.GetUser(User.Identity.Name);
                party.Location = string.Empty;
                pageView.Party = party;
                return View(pageView);
            }
            catch (ArgumentNullException aue)
            {
                ModelState.AddModelError("", aue.Message);
                PartyPublishPageView pageView = new PartyPublishPageView();
                pageView.Type = this.partyService.GetPartyType()
                    .Select(c => new SelectListItem { Text = c.Name, Value = c.PartyType.ToString() })
                    .ToList<SelectListItem>();
                pageView.User = this.userService.GetUser(User.Identity.Name);
                party.Location = string.Empty;
                pageView.Party = party;
                return View(pageView);
            }
            catch (ArgumentException ae)
            {
                ModelState.AddModelError("Party.EndDate", ae.Message);
                PartyPublishPageView pageView = new PartyPublishPageView();
                pageView.Type = this.partyService.GetPartyType()
                    .Select(c => new SelectListItem { Text = c.Name, Value = c.PartyType.ToString() })
                    .ToList<SelectListItem>();
                pageView.User = this.userService.GetUser(User.Identity.Name);
                party.Location = string.Empty;
                pageView.Party = party;
                return View(pageView);
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", "活动发布失败，请检查或者重试！");
                PartyPublishPageView pageView = new PartyPublishPageView();
                pageView.Type = this.partyService.GetPartyType()
                    .Select(c => new SelectListItem { Text = c.Name, Value = c.PartyType.ToString() })
                    .ToList<SelectListItem>();
                pageView.User = this.userService.GetUser(User.Identity.Name);
                party.Location = string.Empty;
                pageView.Party = party;
                return View(pageView);
            }

            return View();
        }


        [HttpGet]
        public ActionResult Attend(int? id)
        {
            if (id == null)
            {
                throw new ArgumentNullException("Id cannot be null!");
            }
            AttendPageView pageView = new AttendPageView();
            pageView.Party = this.partyService.GetParty(id ?? 0);
            DLM.Domain.Model.User user = this.userService.GetUser(this.User.Identity.Name);
            pageView.User = user;
            if (user != null)
            {
                pageView.Bonus = this.userService.GetBonus(user.UserID);
            }

            return View(pageView);
        }

        [HttpPost]
        [UserAuthorize]
        public ActionResult Attend(int partyID, int userID, FormCollection collection)
        {
            try
            {
                PartyPageView view = new PartyPageView();
                view.UserName = User.Identity.Name;
                view.Party = this.partyService.GetParty(partyID); //new Party { PartyID = partyID };

                this.partyService.Attend(view);
                return RedirectToAction("Default", "Home", new { publishid = 0, engagedid = 0 });
            }
            catch (PublishFailedException pfe)
            {
                AttendPageView pageView = new AttendPageView();
                pageView.Party = this.partyService.GetParty(partyID);
                DLM.Domain.Model.User user = this.userService.GetUser(userID);
                pageView.User = user;
                if (user != null)
                {
                    pageView.Bonus = this.userService.GetBonus(user.UserID);
                }
                ModelState.AddModelError("", pfe.Message);
                return View(pageView);
            }
            catch (BounsNotEnoughException be)
            {
                AttendPageView pageView = new AttendPageView();
                pageView.Party = this.partyService.GetParty(partyID);
                DLM.Domain.Model.User user = this.userService.GetUser(userID);
                pageView.User = user;
                if (user != null)
                {
                    pageView.Bonus = this.userService.GetBonus(user.UserID);
                }
                ModelState.AddModelError("", be.Message);
                return View(pageView);
            }

            return View();
        }


        [HttpPost]
        [UserAuthorize]
        public ActionResult Quit(PartyDetailPageView views, int partyID, FormCollection collection)
        {
            PartyPageView view = new PartyPageView();
            view.UserName = User.Identity.Name;
            view.Party = new Party { PartyID = partyID };
            this.partyService.Quit(view);
            return Content("");
        }

        [HttpPost]
        [UserAuthorize]
        [ValidateMvcCaptcha]
        public ActionResult SubmitRemark(int? id, FormCollection collection)
        {
            if (id < 0)
            {
                throw new ArgumentNullException("Id cannot be null!");
            }

            if (string.IsNullOrEmpty(collection["txtContent"]))
            {
                Response.StatusCode = 500;
                return Content("评论内容不允许为空");
            }

            if (!string.IsNullOrEmpty(collection["hdIsRate"]) && collection["hdIsRate"] == "True")
            {
                if (string.IsNullOrEmpty(collection["hdRate"] ))
                {
                    Response.StatusCode = 500;
                    return Content("评分不允许为空");
                }
            }
            // var captchaSuccess = ReCaptcha.Validate("6LdYRtESAAAAAInpSF9yl6Z2awmd8-hYgXfc7Rvg");
            if (ModelState["_mvcCaptchaText"] != null && ModelState["_mvcCaptchaText"].Errors.Count > 0)
            {
                Response.StatusCode = 500;
                //ModelState.AddModelError("", "验证码不匹配，请重新输入！");
                return Content("验证码不匹配，请重新输入!");
            }
            Remark r = new Remark
            {
                PartyID = id ?? 0,
                CreateDate = DateTime.Now,
                Content = collection["txtContent"].ToString(),


                UserID = userService.GetUser(User.Identity.Name).UserID
            };
            if (!string.IsNullOrEmpty(collection["hdIsRate"]) && collection["hdIsRate"] == "True")
            {
                r.Rate = int.Parse(collection["hdRate"].ToString());
            }
            else
            {
                r.Rate = 100;
            }
            this.partyService.AddRemark(r);
            var list = this.partyService.GetRemarkDTO(id ?? 0, 0, 20);
            return View("_Remark", list);
        }

        [HttpGet]
        [UserAuthorize]
        public ActionResult Invitation(int? id, int? party)
        {
            var list = this.userService.MyFriend(User.Identity.Name, id ?? 0, 20);
            InvitationPageView view = new InvitationPageView
            {
                Friends = list,
                PartyID = party ?? 0
            };
            return View(view);

        }

        [HttpPost]
        [UserAuthorize]
        public ActionResult BatchInvitation(FormCollection collection, int partyID, string[] checkedid)
        {
            try
            {
                List<Invitation> inviteList = new List<Invitation>();
                if (checkedid != null)
                {
                    foreach (var item in checkedid)
                    {
                        Invitation invitation = new Invitation
                        {
                            UserID = int.Parse(item),
                            IsConfirmed = false,
                            InviteDate = DateTime.Now,
                            PartyID = partyID,
                            SenderAccount = User.Identity.Name
                        };
                        inviteList.Add(invitation);
                    }
                }
                this.partyService.Invite(inviteList);
            }
            catch (Exception ex)
            {

                ModelState.AddModelError("", ex.Message);
                return View("Invitation");
            }

            return RedirectToAction("Invitation", new { party = partyID });
        }

        [HttpPost]
        [UserAuthorize]
        public ActionResult Invitation(int userID, int partyID)
        {
            try
            {
                Invitation invitation = new Invitation
                {
                    UserID = userID,
                    IsConfirmed = false,
                    InviteDate = DateTime.Now,
                    PartyID = partyID,
                    SenderAccount = User.Identity.Name
                };
                this.partyService.Invite(invitation);
            }
            catch (PartyEngagedException ex)
            {
                Response.StatusCode = 500;
                return Content("该会员已经参加了该活动！");
            }
            catch (InvitationExistException ie)
            {
                Response.StatusCode = 500;
                return Content("您已经邀请了该会员！");
            }

            return Content("");
        }

        [UserAuthorize]
        [HttpGet]
        public ActionResult MyInvitation(int? invitateid, int? historyid)
        {
            int pageIndex;
            int.TryParse(Request.QueryString["historyid"], out pageIndex);
            MyInvitationPageView pageView = new MyInvitationPageView();
            var invitationList = this.partyService.GetInvitationDTO(User.Identity.Name, invitateid ?? 0, 20);
            pageView.MyInvitations = invitationList;
            var histories = this.partyService.GetInvitationHistoryDTO(User.Identity.Name, pageIndex, 20);
            pageView.Histories = histories;
            if (Request.IsAjaxRequest())
            {
                if (invitateid != null)
                {
                    return View("_MyInvitation", pageView.MyInvitations);
                }
                if (historyid != null)
                {
                    return View("_InvitationHistory", pageView.Histories);
                }
            }
            return View(pageView);
        }

        [UserAuthorize]
        [HttpPost]
        public ActionResult ConfrimInvite(int? id, int? page)
        {
            if (id == 0)
            {
                ModelState.AddModelError("", "要参加的活动不允许为空！");
                return View("_MyInvitation");
            }
            this.partyService.ConfirmInvitation(id.Value);
            var list = this.partyService.GetInvitationDTO(User.Identity.Name, page ?? 0, 20);
            return View("_MyInvitation", list);
        }

        [HttpPost]
        public ActionResult PartySearch(CountrySelectionPageView pageView, FormCollection collectiond)
        {
            string type = string.Empty;
            if (collectiond["hdPartySearchType"] != null)
            {
                type = Server.HtmlEncode(collectiond["hdPartySearchType"].ToString());
            }


            switch (type)
            {
                case "Province":
                    return RedirectToAction("PartySearch", new { type = "Province", location = pageView.SelectedProvince + "-" + pageView.SelectedCity + "-" + pageView.SelectedZone });
                case "Date":
                    return RedirectToAction("PartySearch", new { type = "Date", partyDate = pageView.SelectedDate });

                case "Category":
                    return RedirectToAction("PartySearch", new { type = "Category", partyType = pageView.SelectedCategory });
                case "Or":
                    return RedirectToAction("PartySearch", new { type = "Or", location = pageView.SelectedProvince + "-" + pageView.SelectedCity + "-" + pageView.SelectedZone, partyType = pageView.SelectedCategory, partyDate = pageView.SelectedDate });
                case "All":
                    return RedirectToAction("PartySearch", new { type = "All", location = pageView.SelectedProvince + "-" + pageView.SelectedCity + "-" + pageView.SelectedZone , partyType = pageView.SelectedCategory, partyDate = pageView.SelectedDate });
                default:

                    return RedirectToAction("PartySearch", new { type = "", location = pageView.SelectedProvince + "-" + pageView.SelectedCity + "-" + pageView.SelectedZone, partyType = pageView.SelectedCategory, partyDate = pageView.SelectedDate });
            }
            return View();
        }

        [HttpGet]
        public ActionResult PartySearch(int? pageIndex, string type, string location, string partyType, string partyDate)
        {
            try
            {
                var result = this.partyService
             .SearchParty(pageIndex ?? 0, 20, type, Server.HtmlEncode(location),
             Server.HtmlEncode(partyType), Server.HtmlEncode(partyDate));
                return View(result);
            }
            catch (Exception ex)
            {

                LoggingFactory.GetLogger().Error(ex.Message, ex);
                return View("Error");
            }
         
        }

        [HttpPost]
        [UserAuthorize]
        public ActionResult EmailInvitate(FormCollection collection, int partyID)
        {
            string name = collection["EmailInvitation.AccountName"] == null ? string.Empty : collection["EmailInvitation.AccountName"].ToString();
            string email = collection["EmailInvitation.Email"] == null ? string.Empty : collection["EmailInvitation.Email"].ToString();
            try
            {
                EmailInvitation invitation = new EmailInvitation
                {
                    PartyID = partyID,
                    AccountName = name,
                    Email = email,
                    SendDate = DateTime.Now,
                    Content = User.Identity.Name
                };
                this.partyService.SendEmailInvitation(invitation);
                return RedirectToAction("View", new { id = partyID });
            }
            catch (Exception)
            {

                ModelState.AddModelError("", "请输入要邀请人的信息");
                return View("Invitation");
            }

        }

        [HttpPost]
        [UserAuthorize]
        public ActionResult Print(int partyID)
        {
            var list = this.userService.Participated(partyID, 0, 150);
            return View("_Print", list);

        }

        [HttpGet]
        [UserAuthorize]
        public ActionResult ShowAttendNotice()
        {
            return PartialView("_AttendNotice");
        }

        [HttpGet]
        [UserAuthorize]
        public ActionResult GetPartyAlbum(int id)
        {
            if (Request.IsAjaxRequest())
            {
                Response.Cache.SetCacheability(HttpCacheability.NoCache);
                
                PartyDetailPageView view = new PartyDetailPageView();
                view = this.partyService.ViewParty(id, User.Identity.Name);
                view.Album = this.partyService.GetPartyAlbum(id, 0, 8);
                return View("_PartyAlbum", view);
            }
            return View();
        
        }

        [HttpPost]
        [UserAuthorize]
        public ActionResult UploadPartyPhoto(HttpPostedFileBase uploadFile, FormCollection collection, int id)
        {
            if (uploadFile == null)
            {
                ModelState.AddModelError("Photo", "Photo Cannot be null!");
                return Content("请选择要上传的照片");

            }

            if (!imageType.Contains(uploadFile.ContentType))
            {
                ModelState.AddModelError("Photo", "Invalidate type!");
                return Content("您上传的照片格式不符合要求,请上传jpg格式的图片");
            }

            if (uploadFile.ContentLength / 1024 / 1024 > 4)
            {
                ModelState.AddModelError("Photo", "Invalidate type!");
                return Content("照片大小请不要超过4MB");
            }
            if (uploadFile != null)
            {
                string title = Path.GetRandomFileName() + ".jpg";
                string parentDir = Server.MapPath("~/Files/Party/" + id + "/Album/");
                string subDir = Server.MapPath("~/Files/Party/" + id + "/Album/Thumb/");

                // Save todatabase
                PartyAlbum album = new PartyAlbum 
                {
                    Account = User.Identity.Name,
                    CreateDate = DateTime.Now,
                    PartyID = id,
                    PhotoName = title
                };

                try
                {
                    this.partyService.AddAlbum(album);

                    // Save file
                    if (!Directory.Exists(parentDir))
                    {
                        Directory.CreateDirectory(parentDir);
                        if (!Directory.Exists(subDir))
                        {
                            Directory.CreateDirectory(subDir);
                        }
                    }

                    Image.MakeThumbnailImg(uploadFile, parentDir + title, 720, 540);

                    Image.MakeThumbnailImg(uploadFile, subDir + title, 75, 75);
                }
                catch (PhotoEnoughException)
                {
                    Response.StatusCode = 500;
                    return Content("系统最多允许上传八张相片");
                }

                PartyDetailPageView view = new PartyDetailPageView();
                view = this.partyService.ViewParty(id, User.Identity.Name);
                view.Album = this.partyService.GetPartyAlbum(id, 0, 8);
                return View("_PartyAlbum", view);


            }
            return View();
        }
    }
}